import logging
from typing import List

from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.dnspod.v20210323 import dnspod_client, models

from app.schemas.dns import (
    DNSRecord,
    DNSRecordCreate,
    DNSRecordIdentifier,
    DNSRecordStatus,
    DNSRecordType,
    DNSRecordUpdate,
    DomainSummary,
)
from app.services.cloud_providers.base import BaseProvider

logger = logging.getLogger(__name__)


class TencentProvider(BaseProvider):
    """腾讯云 (DNSPod) 适配器。"""

    def __init__(self, access_key: str, secret_key: str, region: str = "") -> None:
        super().__init__(access_key, secret_key, region)
        cred = credential.Credential(access_key, secret_key)
        http_profile = HttpProfile()
        http_profile.endpoint = "dnspod.tencentcloudapi.com"
        client_profile = ClientProfile()
        client_profile.httpProfile = http_profile
        self.client = dnspod_client.DnspodClient(cred, region or "", client_profile)

    def list_domains(self) -> List[DomainSummary]:
        try:
            req = models.DescribeDomainListRequest()
            resp = self.client.DescribeDomainList(req)
            results = []
            for item in resp.DomainList:
                results.append(
                    DomainSummary(
                        domain=item.Name,
                        provider="tencent",
                        record_count=item.RecordCount,
                    )
                )
            return results
        except TencentCloudSDKException as err:
            logger.error(f"Tencent list_domains failed: {err}")
            raise

    def list_records(self, domain: str) -> List[DNSRecord]:
        try:
            req = models.DescribeRecordListRequest()
            req.Domain = domain
            # 默认分页可能需要处理，这里简化为获取第一页
            resp = self.client.DescribeRecordList(req)
            results = []
            for item in resp.RecordList:
                results.append(
                    DNSRecord(
                        id=str(item.RecordId),
                        provider="tencent",
                        domain=domain,
                        record_type=DNSRecordType(item.Type.upper()),
                        name=item.Name,
                        value=item.Value,
                        ttl=item.TTL,
                        status=DNSRecordStatus.active if item.Status == "ENABLE" else DNSRecordStatus.paused,
                    )
                )
            return results
        except TencentCloudSDKException as err:
            logger.error(f"Tencent list_records failed: {err}")
            raise

    def create_record(self, payload: DNSRecordCreate) -> DNSRecord:
        try:
            req = models.CreateRecordRequest()
            req.Domain = payload.domain
            req.SubDomain = payload.name
            req.RecordType = payload.record_type.value
            req.RecordLine = "默认"  # 必填，默认线路
            req.Value = payload.value
            req.TTL = payload.ttl
            req.Status = "ENABLE" if payload.status == DNSRecordStatus.active else "DISABLE"

            resp = self.client.CreateRecord(req)
            
            # 返回构造的对象，因为 API 只返回 ID
            return DNSRecord(
                id=str(resp.RecordId),
                provider="tencent",
                domain=payload.domain,
                record_type=payload.record_type,
                name=payload.name,
                value=payload.value,
                ttl=payload.ttl,
                status=payload.status,
            )
        except TencentCloudSDKException as err:
            logger.error(f"Tencent create_record failed: {err}")
            raise

    def update_record(self, domain: str, payload: DNSRecordUpdate) -> DNSRecord:
        try:
            req = models.ModifyRecordRequest()
            req.Domain = domain
            req.RecordId = int(payload.id)
            req.RecordType = payload.record_type.value if payload.record_type else None
            req.RecordLine = "默认"
            req.Value = payload.value
            req.TTL = payload.ttl
            # DNSPod ModifyRecord requires all fields or it might reset them? 
            # Actually ModifyRecord allows optional parameters but we must be careful.
            # For this demo, we assume the payload contains what needs to be changed.
            # However, DNSPod API might require SubDomain (Name) if we are modifying it.
            # Let's assume we are modifying 'Value' mostly.
            # If Name is missing, we might need to fetch it first.
            # To keep it simple for this demo, we assume Name is passed or we don't change it.
            # Wait, ModifyRecordRequest requires 'SubDomain'.
            if payload.name:
                req.SubDomain = payload.name
            else:
                # If name is not provided in update, we fail or need to fetch.
                # Let's fetch the record first to get current values.
                current_records = self.list_records(domain)
                current = next((r for r in current_records if r.id == payload.id), None)
                if not current:
                    raise KeyError("Record not found")
                req.SubDomain = current.name
                if not req.RecordType:
                    req.RecordType = current.record_type.value
                if not req.Value:
                    req.Value = current.value
                if not req.TTL:
                    req.TTL = current.ttl
            
            if payload.status:
                req.Status = "ENABLE" if payload.status == DNSRecordStatus.active else "DISABLE"

            resp = self.client.ModifyRecord(req)
            
            return DNSRecord(
                id=str(resp.RecordId),
                provider="tencent",
                domain=domain,
                record_type=DNSRecordType(req.RecordType),
                name=req.SubDomain,
                value=req.Value,
                ttl=req.TTL or 600,
                status=payload.status or DNSRecordStatus.active,
            )
        except TencentCloudSDKException as err:
            logger.error(f"Tencent update_record failed: {err}")
            raise

    def delete_record(self, domain: str, payload: DNSRecordIdentifier) -> None:
        try:
            req = models.DeleteRecordRequest()
            req.Domain = domain
            req.RecordId = int(payload.id)
            self.client.DeleteRecord(req)
        except TencentCloudSDKException as err:
            logger.error(f"Tencent delete_record failed: {err}")
            raise

    def batch_delete_records(self, domain: str, record_ids: List[str]) -> int:
        try:
            req = models.DeleteRecordBatchRequest()
            req.Domain = domain
            req.RecordIdList = [int(rid) for rid in record_ids]
            resp = self.client.DeleteRecordBatch(req)
            # Resp doesn't return count, but we assume success
            return len(record_ids)
        except TencentCloudSDKException as err:
            logger.error(f"Tencent batch_delete_records failed: {err}")
            raise
